package org.shj.thread.basic;

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

import org.shj.thread.util.Util;

/**
 *
 * @author Shen Huang Jian
 * @date 2018-01-02 16:30:24
 */
public class ConditionDemo {
	
	private static Lock lock = new ReentrantLock();
	private static Condition condition = lock.newCondition();

	public static void main(String[] args){
		for(int i = 0 ; i < 5; i++){
			new Thread(new Wait()).start();
		}
		Util.sleep(1);
		
		for(int i = 0 ; i < 5; i++){
			new Thread(new Notify()).start();
		}
		
	}
	
	static class Wait implements Runnable{
		public void run(){
			lock.lock();
			try{
				System.out.println("Wait thread " + Thread.currentThread().getName() + " begin to wait");
				condition.await(); //线程释放锁，并在此等待,直到其它线程调用 condition.signal()并释放锁之后返回，并获得锁
				System.out.println("Wait thread " + Thread.currentThread().getName() + " is awaken.");
			}catch(InterruptedException e){
				
			}finally{
				lock.unlock();
			}
		}
	}
	
	static class Notify implements Runnable{
		public void run(){
			lock.lock();
			try{
				System.out.println("Notify thread " + Thread.currentThread().getName() + " begin to wake wait thread.");
				condition.signal();
				System.out.println("Notify thread " + Thread.currentThread().getName() + " after notify");
			}finally{
				lock.unlock();
			}
		}
	}
}
